<template>
    <div id='xterm'></div>
</template>

<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref } from 'vue'
import 'xterm/css/xterm.css'
import { Terminal } from 'xterm';
import { FitAddon } from "xterm-addon-fit";

const wsInstance = ref<WebSocket>()
const xtermInstance = ref<Terminal>()

onMounted(() => {
  setTimeout(() => {
    initTerm()
  }, 200);
})

onBeforeUnmount(() => {
  wsInstance.value?.close()
  xtermInstance.value?.dispose()
})

//初始化当前系统环境，返回终端的 pid，标识当前终端的唯一性
const initSysEnv = async () =>
  await fetch("http://127.0.0.1:8003/terminal", {
    method: 'post'
  })
    .then((res) => res.json())
    .then((res) => res)
    .catch((err) => {
      throw new Error(err);
    });

const initSocket = (pid: string) => {
  const ws = new WebSocket('ws://localhost:8003/socket/' + pid)
  wsInstance.value = ws
  console.log('ws', ws)
  bindEvent(ws)
}

const initTerm = async () => {
    const element = document.getElementById('xterm')
    if (!element) return
    // 设置了cols或者fitAddon.fit(); 当一行字符超过80个过会替换现在的内容，否则换行
    const term = new Terminal({
      cursorBlink: true, // 关闭闪烁
      cursorStyle: 'underline', // 光标样式
      scrollback: 100, //当行的滚动超过初始值时保留行视窗，越大回滚能看到的内容越多
      fontFamily: 'Menlo, Monaco, "Courier New", monospace',
      fontWeight: 400,
      fontSize: 13,
      rows: 50,
      cols: 130
    })
    const fitAddon = new FitAddon()
    const pid = await initSysEnv()

    term.loadAddon(fitAddon)
    fitAddon.fit()
    term.open(element)
    term.focus()
    term.onData((data: any) => {
      console.log('data', data)
      wsInstance.value?.send(data)
    })
    initSocket(pid)
    xtermInstance.value = term
  }


const bindEvent = (ws: WebSocket) => {
  ws.addEventListener('open', handleOpen, false)
  ws.addEventListener('close', handleClose, false)
  ws.addEventListener('error', handleError, false)
  ws.addEventListener('message', handleMessage, false)
}

const handleOpen = () => {
    // initTerm()
  }

  const handleMessage = (event: MessageEvent) => {
    console.log('event.data.toString()', event.data.toString())
    // 接收推送的消息
    xtermInstance.value!.write(event.data.toString());
  }

  const handleClose = () => {

  }

  const handleError = () => {

  }

</script>

<style scoped lang="scss">
#xterm {
  width: 100%;
  height: 100%;
}
</style>
